// Form1.h
//
// This file implements a Form-derived class that is also
// a remote TPI.NET client. It demonstrates how to connect
// to a remote TLA and subscribe to events raised by TPI.NET.
/////////////////////////////////////////////////////////////

#include "StdAfx.h"
#using <mscorlib.dll>
#using <system.windows.forms.dll>
#using <system.drawing.dll>
#using <system.dll>

// Contains all the TPI.NET types and utility classes.
#using "TlaNetInterfaces.dll" 

#include "form1.h"

using namespace CPPRemoteClientSample;
using namespace System;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace Tektronix::LogicAnalyzer::TpiNet;
using namespace Tektronix::LogicAnalyzer::Common;


// The constructor connects to the remote TLA application and 
// subscribes to two of the ITlaRunControl events.
Form1::Form1(void)
{
	InitializeComponent();
	
	String* version = 0;
	
	// The assembly TlaNetInterfaces, which this project references,
	// contains a utility class named RemoteTlaSystem. It has a
	// Connect() static method which is used to set up a connection
	// to a remote TLA. To connect, an application configuration file
	// named TpiNetRemoteClient.config is used. This file contains
	// the information needed to configure this application to
	// communicate with a TLA running on the local host. The
	// configuration file can be modified to connect to a TLA
	// on a network.
	// NOTE: For the call to Connect() to succeed, the file
	// TpiNetRemoteClient.config must be in the same directory as
	// the application executable.
	try {
		m_system = RemoteTlaSystem::Connect("TpiNetRemoteClient.config");
		version = m_system->SWVersion;
	}
	catch (...) {
		
		// Failed to connect to the application. Show a warning message.
		MessageBox::Show("Could not connect to the TLA application. Make sure the TLA application is running before starting the client application. Also make sure the configuration file is located in the executable directory.");
		m_system = 0;
	}
	if (!m_system) {
		m_versionLabel->Text = "Could not connect to TLA application";
		m_runButton->Enabled = false;
		m_runButton->Text = S"Cannot run TLA";
	}
	else {

		// Connection was successful. Now subscribe to TPI.NET events.
		// In order to subscribe, an intermediate shim object, whose type
		// is known to the TLA, is needed. In TPI.NET, we call these 
		// shims "remoters." To subscribe to a remote TPI.NET event
		// follow these steps.
		//
		// 1 )Create a remoter object of the appropriate type (see the 
		// document "TPI.NET Remote Client Design Guide for details.)
		// 
		// 2) Subscribe the remoter object to the TPI.NET event using
		// a delegate for the remoter method OnRemoteEvent().
		//
		// 3) Subscribe a local class method to the RemoteEventOccurred 
		// event of the remoter object.
		//
		// When the subscribed TPI.NET event is raised, the TLA will
		// make a callback to the remoter object. The remoter will,
		// in turn, raise its RemoteEventOccurred event; and the local
		// event handler will be called with same arguments that the
		// TLA application passed to the remoter.
		//
		// These steps are demonstrated in the code below, which
		// subscribes to ITlaRunControl.RunStarted and
		// ITlaRunControl.RunCompleted.

		// Subscribe to ITlaRunControl.RunStarted.
		m_runStartRemoter = new EventRemoter;
		m_system->RunControl->add_RunStarted(new EventHandler (m_runStartRemoter, &EventRemoter::OnRemoteEvent));
		m_runStartRemoter->add_RemoteEventOccurred(new EventHandler (this, &Form1::OnRunStarted));

		// Subscribe to ITlaRunControl.RunCompleted.
		m_runCompleteRemoter = new EventRemoter;
		m_system->RunControl->add_RunCompleted(new EventHandler(m_runCompleteRemoter, &EventRemoter::OnRemoteEvent));
		m_runCompleteRemoter->add_RemoteEventOccurred(new EventHandler (this, &Form1::OnRunCompleted));
		
		m_versionLabel->Text = String::Format 
			(S"TLA Software Version is {0}", version);
		
		// Local events don't need shims.
		add_Closed(new EventHandler(this, &Form1::OnFormClosed));
		m_runButton->add_Click(new EventHandler(this, &Form1::OnRunButton));
	}
}

// This method initializes the size and position of controls 
// on the surface of the Form.
void Form1::InitializeComponent()
{
    m_versionLabel = new Label;
    m_runButton = new Button;
    m_label1 = new Label;
    m_eventLabel = new Label;
    SuspendLayout();
    // 
    // versionLabel
    // 
    m_versionLabel->Location = System::Drawing::Point(16, 24);
    m_versionLabel->Size = System::Drawing::Size(256, 32);
    m_versionLabel->TabIndex = 0;
    m_versionLabel->Text = S"label1";
    // 
    // runButton
    // 
    m_runButton->Location = System::Drawing::Point(16, 64);
    m_runButton->Size = System::Drawing::Size(248, 32);
    m_runButton->TabIndex = 1;
    m_runButton->Text = S"Run the TLA";
    // 
    // label1
    // 
    m_label1->Location = System::Drawing::Point(16, 120);
    m_label1->Size = System::Drawing::Size(256, 24);
    m_label1->TabIndex = 2;
    m_label1->Text = S"Most Recent Run Event:";
    // 
    // eventLabel
    // 
    m_eventLabel->Location = System::Drawing::Point(16, 152);
    m_eventLabel->Name = S"eventLabel";
    m_eventLabel->Size = System::Drawing::Size(256, 32);
    m_eventLabel->TabIndex = 3;
    m_eventLabel->Text = S"None.";
    // 
    // CSRemoteClient
    // 
    AutoScaleBaseSize = System::Drawing::Size(6, 15);
    ClientSize = System::Drawing::Size(292, 208);
    Controls->Add(m_eventLabel);
    Controls->Add(m_label1);
    Controls->Add(m_runButton);
    Controls->Add(m_versionLabel);
    
    Text = "Remote TPI.NET Client";
    ResumeLayout(false);
}


// Event handler for the ITlaRunControl.RunStarted event.
void Form1::OnRunStarted (System::Object*, System::EventArgs* args)
{
    m_eventLabel->Text = S"An acquisition started.";
    m_runButton->Enabled = false;
}


// Event handler for the ITlaRunControl.RunCompleted event.
void Form1::OnRunCompleted (System::Object*, System::EventArgs* args)
{
    m_eventLabel->Text = S"An acquisition completed.";
    m_runButton->Enabled = true;
}


// Starts a TLA acquistion when the user clicks the 
// "Run the TLA" button.
void Form1::OnRunButton (System::Object*, System::EventArgs* args)
{
    if (m_system) {
        m_system->RunControl->Run();
    }
}


// Removes TPI.NET event subscriptions when the user exits the
// application. TPI.NET clients should always clean up their
// subscriptions before exiting.
void Form1::OnFormClosed (System::Object*, System::EventArgs* args)
{
    if (m_system) {
        m_system->RunControl->remove_RunStarted(new EventHandler (m_runStartRemoter, &EventRemoter::OnRemoteEvent));
		m_system->RunControl->remove_RunCompleted(new EventHandler(m_runCompleteRemoter, &EventRemoter::OnRemoteEvent));
    }
    
}

